// 1. 导包 --------------------------------
const express = require('express');
const bodyParser = require('body-parser');
const multer =  require('multer');
let app = express();
// 1.1 导入db.js 文件来使用 -----------------------------
const db = require('./utils/db.js');

// 1.2 创建 multer 上传组件-------------------------------
const upload = multer({dest: './web/uploads'})

// 2. 中间件    -------------------------------
//2.1 暴露 静态文件夹
app.use(express.static('web'));
//2.2 注册 bodyParser 中间件
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 3. 注册路由
// 封装数据方法 优化  ---------------------------
/**
* @description: 创建 返回给浏览器的 消息对象
* @param {Number} code: 状态码
* @param {String} msg:  给浏览器的消息
* @param {Object} data: 给浏览器的数据
* @return: 
*/
function makeMsgData(code = 200, msg = '成功', data = 'null') {
    return {
        code,
        msg,
        data
    }
};
// 3.1 注册 登录 路由       -------------------------------
app.post('/login', (req, res) => {
    //a.准备 响应消息对象
    let msgObj = makeMsgData(200, '登录成功');
    //b.判断，如果 登录失败，就 修改 消息对象里的 内容
    if (req.body.username != 'admin' || req.body.password != '123456') {
        msgObj.code = 400;
        msgObj.msg = '用户名或密码错误'
    }
    //c.向浏览器 发送 消息对象
    res.send(msgObj);
});
// 3.2 注册 英雄列表 路由   ---------------------------------
app.get('/list', (req, res) => {
    let backData = makeMsgData(200, '获取成功');
    // a. 获取 所有 未删除的 英雄
    let heroList = db.getHeros();

    // b. 判断 是否有 数据
    if( heroList != null && heroList.length > 0) {
        // 将 查询到的  数据 设置给 响应 数据对象
        backData.data = heroList;
    } else {
        // 修改 响应数据对象的内容
        backData.code = 201;
        backData.msg = '参数有错, 无法查询';
    }
    //c.向浏览器 发送 消息对象
    res.send(backData);

});
// 3.3 注册 新增英雄 路由   ---------------------------------
app.post('/add',upload.single('icon'),(req, res) =>{
    //a.准备消息对象
    let msgData = makeMsgData(201, '新增成功');

    //b.校验数据
    if(req.body.name == '' || req.body.skill == '' || req.file == undefined) {
        msgData.code = 407;
        msgData.msg = '参数有缺失，请检查后再提交';
    } else {
        //c.接收 浏览器 提交来的 数据，并封装到 对象中
        let addData = {
            name: req.body.name,
            skill: req.body.skill,
            icon: req.file.filename
        } 
        // d. 将 数据对象提交 到 db.js
        const isOk = db.addHero(addData);

         // e. 判断新增结果， 返回不同的消息
        if(!isOk) {
            msgData.code = 400,
            msgData.msg = '参数错误'
        }
    }

    // f. 返回数据
    res.send(msgData);

});
// 3.4 注册 删除英雄 路由   ---------------
app.post('/delete', (req, res)=> {
    // a. 获取 请求 报文中 删除英雄id
        let heroId = req.body.id;
    // b. 调用db.js 删除方法
        let isOk = db.deleteHeroById(heroId);
    // c. 返回消息对象
    let msgData = makeMsgData(201, '删除成功');
        
    // d. 判断删除结果 设置返回对象
    if(!isOk) {
        msgData.code = 400;
        msgData.msg = '参数有错'
    }
    // e. 返回数据
    res.send(msgData);
});
// 3.5 注册 查询 英雄 路由  -----------------
app.get('/search', (req, res)=>{
    // a. 获取 url 中 id
    let heroId = req.query.id;
    // b. 调用db.js 查询方法
    let isOk =  db.getHeroById(heroId);
    // c. 准备消息对象
    let msgData = makeMsgData(200, '查询成功', heroId);
    // d. 判断结果
    if(!isOk) {
        msgData.data = 400;
        msgData.msg = '参数错误'
    }
    // e. 返回消息 浏览器
    res.send(msgData);
});
// 3.6 注册 编辑 英雄 路由  ----------------------------
app.post('/edit', upload.single('icon') ,(req, res) => {
    // a. 获取数据
    let editData = {
        id: req.body.id,
        name: req.body.name,
        skill: req.body.skill,
        icon: req.file ? req.file.filename : ''
    };
    // b. 调用db.js 编辑方法
    let isOk = db.editHero(editData);
    // c. 返回数据
    let msgData = makeMsgData(203, '编辑成功');
    if(!isOk){
        msgData.code = 400;
        msgData.msg = '参数错误'
    }
    // d. 返回数据 给浏览器
    res.send(msgData);
});

// 4. 启动服务器    --------------------------
const PORT = 3747;
app.listen(PORT, (err) => {
    if(err == null){
        console.log('【英雄】服务器启动成功:'+ PORT);
    } else {
        console.log('启动失败' + err.message);
    }
});

